%%% shoutcast.erl - an implementation of the shoutcast protocol
%%%
%%% The MIT License
%%%
%%% Copyright (c) 2008 hellomatty@gmail.com
%%%
%%% Permission is hereby granted, free of charge, to any person obtaining a copy
%%% of this software and associated documentation files (the "Software"), to deal
%%% in the Software without restriction, including without limitation the rights
%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%%% copies of the Software, and to permit persons to whom the Software is
%%% furnished to do so, subject to the following conditions:
%%%
%%% The above copyright notice and this permission notice shall be included in
%%% all copies or substantial portions of the Software.
%%%
%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%%% THE SOFTWARE.
%%%

-module(shoutcast).
-export([out/1,process/2]).

-import(bbcprogrammes).
-include_lib("defs.hrl").
-include_lib("util.hrl").
-include_lib("yaws_api.hrl").

-define(XSPF_MIME, "application/xspf+xml").
-define(AUDIO_MIME, "audio/mpeg").

-define(XSPF_HEADER,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">
<title>BBC Radio</title>
<tracklist>
").
-define(XSPF_ITEM,"<track><location>~s</location><title>~s</title><creator>~s</creator><album>~s</album><annotation>~s</annotation></track>").
-define(XSPF_FOOTER,"</tracklist></playlist>").

out(A) ->
  process(string:tokens(A#arg.server_path, "/"),[]).

process(["programmes"],[]) ->
  YawsPid = self(),
  spawn_link(fun() ->
    {ok, Port} = application:get_env(bbc2daap,listen_port),
    {_Genres, Episodes} = gen_server:call(bbcprogrammes_server, state),
    lists:map(fun({Id, Episode}) ->
      Title = Episode#episode.title,
      StreamUrl = lists:flatten(io_lib:format("http://localhost:~B/programme/~B/",[Port,Id])),
      Creator = Episode#episode.service,
      Album = Episode#episode.brand,
      Annotation = Episode#episode.description,
      yaws_api:stream_chunk_deliver(YawsPid, lists:flatten(io_lib:format(?XSPF_ITEM, [StreamUrl, Title, Creator, Album, Annotation])))
    end, Episodes),
    yaws_api:stream_chunk_deliver(YawsPid, ?XSPF_FOOTER),
    yaws_api:stream_chunk_end(YawsPid)
  end),
  {streamcontent, ?XSPF_MIME, ?XSPF_HEADER};
process(["programme",Id],[]) ->
  YawsPid = self(),
  ?D({yaws,self()}),
  EpisodeId = list_to_integer(Id),
  Episode = gen_server:call(bbcprogrammes_server, {episode, EpisodeId}),
  ?D({yaws,self()}),
  spawn(fun() ->
    ?D({streamer,self()}),
    process_flag(trap_exit, true),
    link(YawsPid),
    RTMPPid = gen_server:call(bbcprogrammes_server, {stream, song, id, EpisodeId, self()}),
    loop(YawsPid, RTMPPid)
  end),
  Header = lists:flatten(io_lib:format("icy-name: ~s from ~s", [Episode#episode.title, Episode#episode.service])),
  [{header, Header},
    {streamcontent, ?AUDIO_MIME, <<>>}].

loop(YawsPid, RTMPPid) ->
  receive
    {'EXIT', YawsPid, Reason} ->
     ?D({streamer, yaws_killed, Reason, killing, RTMPPid}),
      exit(RTMPPid, sink_closed),
      exit(normal);
    {'EXIT', RTMPPid, Reason} ->
      ?D({streamer, rtmp_killed, Reason}),
      yaws_api:stream_chunk_end(YawsPid),
      exit(normal);
    {stream, from, _From, audio, Data} ->
      yaws_api:stream_chunk_deliver(YawsPid, Data);
    Backstop ->
      ?D({daap,got,Backstop})
  end,
  loop(YawsPid, RTMPPid).
